<?php

namespace app\site\service;

use app\common\exception\MiException;
use app\model\site\Site;
use app\model\site\SiteUser;
use app\site\service\auth\SiteUserService;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\db\Query;
use think\exception\ValidateException;
use think\Model;
use function jsonError;
use function jsonSuccess;
use function request;
use function validate;

class RequestService
{
    private \think\Request $request;

    protected int $siteUserId;
    protected SiteUser $siteUser;
    protected Site $site;
    protected int $siteId;

    protected $list;
    protected Query $query;
    protected $actionFlag;  // 最后一次操作的标记
    protected $row;
    protected $validate;
    protected Model $model;

    public function __construct(){
        $this->request = request();
        $siteUserSer = new SiteUserService();
        $this->siteUser = $siteUserSer->getLoginInfo();
        $this->siteUserId = $siteUserSer->getLoginId();
        $this->siteId = $this->siteUser->site_id;
        $this->site = Site::find($this->siteId);
    }

    /**
     * 查询
     * @param $query
     * @return $this
     */
    public function setQuery($query): static
    {
        // 添加站点id条件
        $this->query = $query;
        return $this;
    }

    public function model(Model $model): static
    {
        $this->model = $model;
        return $this;
    }


    /**
     * 排序
     * @param $order
     * @return $this
     */
    public function order($order): static
    {
        if ($order){
            $this->query->order($order);
        }else{
            $field = $this->request->param('field', 'create_time');
            $order = $this->request->param('order', 'desc');
            $this->query->order($field, $order);
        }
        return $this;
    }

    /**
     * 软删除查询
     * @return $this
     */
    public function readDelete(string $delete=''): static
    {
        if ($delete == '') $delete = $this->request->param('delete', 'normal');
        if ($delete == 'delete'){   // 只查询软删除数据
            $this->query->onlyTrashed();
        }elseif ($delete == 'all'){ // 查询全部数据
            $this->query->withTrashed();
        }
        return $this;
    }

    /**
     * 分页查询
     * @return $this
     */
    public function paginate(): static
    {
        $this->actionFlag = 'page_list';
        // 每页显示数目
        $limit = $this->request->param('limit',10);
        $this->list = $this->query->paginate($limit);
        return $this;

    }

    /**
     * 列表查询
     * @return $this
     */
    public function select(): static
    {
        $this->actionFlag = 'list';
        $this->list = $this->query->select();
        return $this;
    }

    public function getList(){
        return $this->list;
    }


    public function validate($validate){
        return $this->validate = $validate;
    }

    /**
     * @throws MiException
     */
    public function add($data=null): static
    {
        $this->actionFlag = 'add';
        $req = $this->request;
        if($req->isPost()){
            if (!$data) $data = $this->request->except(['create_time', 'update_time'], 'post');
            // 站点数据的每个表都需要添加站点id
            $data['site_id'] = $this->siteId;
            // 验证表单数据
            if ($this->validate){
                validate($this->validate)->check($data);
            }

            $ser = new CurdService($this->model);
            $this->row = $ser->create($data);
            return $this;

        }else{
            throw new MiException(REQUEST_ERROR);
        }
    }

    /**
     * @throws MiException
     */
    public function edit($data=null): static
    {
        $this->actionFlag = 'edit';
        if($this->request->isPost()){

            if (!$data) $data = $this->request->except(['create_time', 'update_time'], 'post');

            if(!$id = $data['id']??''){
                throw new MiException(NOT_FOUND);
            }
            // 站点数据的每个表都需要添加站点id
            $data['site_id'] = $this->siteId;
            // 验证表单数据
            if ($this->validate){
                validate($this->validate)->check($data);
            }
            // 更新数据
            $ser = new CurdService($this->model);
            $this->row = $ser->update($data, ['id' => $id]);
            return $this;
        }

        throw new MiException(REQUEST_ERROR);
    }

    /**
     * 删除
     * @param $ids
     * @throws MiException
     */
    public function delete($ids=null): static
    {
        $this->actionFlag = 'del';
        if (!$ids)  $ids = $this->request->param('ids');
        $res = $this->query->where('id', 'in', $ids)->select();
        if (count($res) == 0){
            throw new MiException(NOT_FOUND);
        }
        // 是否彻底删除
        $isForce = $this->request->param('is_force', false);
        $isForce = (bool)$isForce;
        foreach ($res as $v) {
            if ($isForce){
                $v->force()->delete();
            }else{
                $v->delete();
            }
        }

        return $this;
    }



    /**
     * * 删除数据时的级联限制，有级联数据的不允许删除
     * rel_id:关联字段
     * rel_model: 关联模型
     * 必须是二维数组：
     * [
     *   ['rel_id'=> 'cate_id', 'rel_model'=>'ArticleCate'],
     * ]
     *
     * @param Model $model
     * @param array $cascades
     * @return array|string|void
     * @throws MiException
     */
//    public function destroy(Model $model, $ids=''){
//        // 更新数据
//        $ser = new CurdService($model);
//        $req = request();
//        if($req->isPost()){
//            if (!$ids) $ids = $req->param("ids");
//            // 是否彻底删除
//            $isForce = $this->request->param('is_force');
//            $isForce = (bool)$isForce;
//
//            // 删除
//            $ser->destroy($ids, $isForce);
//        }
//
//        throw new MiException(REQUEST_ERROR);
//    }

    public function getPostData(){
        return $this->request->except(['create_time', 'update_time'], 'post');
    }


    public function returnJson(){
        $flag = $this->actionFlag;
        if ($flag == 'page_list'){
            return jsonSuccess([
                'items' => $this->list->items(),
                'total' => $this->list->total(),
            ]);
        }else if ($flag == 'list'){
            return jsonSuccess([
                'items' => $this->list->items(),
            ]);
        }else if($flag == 'add') {
            return jsonSuccess([
                'info' => $this->row,
            ]);
        }else if($flag == 'edit') {
            return jsonSuccess([
                'info' => $this->row,
            ]);
        }else if($flag == 'del') {
            return jsonSuccess();
        }
    }
}
